package com.jc.task.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jc.task.util.EmailUtil;
import com.jc.task.util.RedisUtil;
import org.quartz.*;
import org.quartz.impl.JobDetailImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by yaojie.cao on 2017/3/6.
 */
@Service
public class JobService {

    static final Logger logger = LoggerFactory.getLogger(JobService.class);

    @Autowired(required = false)
    private SchedulerFactoryBean schedulerFactoryBean;

    @Autowired
    private JobTask jobTask;

    @Autowired
    private EmailUtil emailUtil;

    @Autowired
    private RedisUtil redisUtil;


    /**
     * redis添加任务
     *
     * @param body
     * @param triggerIdentity
     * @return
     */
    public synchronized String addTask(String triggerIdentity, String body) throws SchedulerException {
        JSONObject requestBody = JSON.parseObject(body);
        Date date = requestBody.getDate("date");
        String description = requestBody.getString("description");
        String url = requestBody.getString("url");
        String bodyParameter = requestBody.getString("bodyParameter");
        String cronExpression = requestBody.getString("cronExpression");
        addJob(jobTask, date, cronExpression, triggerIdentity, description, url, bodyParameter);
        return "SUCCESS";
    }

    /**
     * 接口添加任务
     *
     * @param job            任务类
     * @param date           任务时间
     * @param cronExpression cron表达式
     * @param identityKey    job和触发器唯一key
     * @param description    触发器的描述
     */
    public synchronized void addJob(Job job, Date date, String cronExpression, String identityKey, String description, String url, String bodyParameter) throws SchedulerException {
        //job类的参数
        JobDataMap jobDataMap = new JobDataMap();
        jobDataMap.put("identityKey", identityKey);
        jobDataMap.put("url", url);
        jobDataMap.put("bodyParameter", bodyParameter);
        jobDataMap.put("description", description);

        //触发器
        Trigger trigger;
        if (date == null && !StringUtils.isEmpty(cronExpression)) {//如果只传cronSchedule
            jobDataMap.put("ifDisposable", false);
            //CronTrigger作业触发器
            trigger = TriggerBuilder.newTrigger()
                    .withIdentity(identityKey)
                    .withDescription(description)
                    .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
                    .build();
        } else if (date != null && StringUtils.isEmpty(cronExpression)) {//如果只传date
            jobDataMap.put("ifDisposable", true);
            //普通作业触发器
            trigger = TriggerBuilder.newTrigger()
                    .withIdentity(identityKey)
                    .withDescription(description)
                    .startAt(date)//执行时间
                    .build();
        } else {//如果都传或者都没有传 直接返回
            return;
        }


        //这是job类的任务
        JobDetailImpl jobDetail = new JobDetailImpl();
        jobDetail.setJobClass(job.getClass());
        jobDetail.setJobDataMap(jobDataMap);
        jobDetail.setKey(new JobKey(identityKey));

        try {
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            logger.error("任务调度器异常:", e);
            emailUtil.sendEmail("任务调度添加异常=任务:" + identityKey + "描述:" + description + " 参数:" + bodyParameter);
            throw e;
        }
        logger.info("添加一个任务=任务名:{},任务时间:{},任务描述：{}，任务回调地址:{},任务参数:{}", identityKey, date != null ? new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date) : cronExpression, description, url, bodyParameter);
    }

    /**
     * 接口删除任务
     *
     * @param identityKey job和触发器唯一key
     */
    public synchronized void deleteJob(String identityKey) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        try {
            scheduler.deleteJob(new JobKey(identityKey));
            redisUtil.del(identityKey);
        } catch (SchedulerException e) {
            logger.error("删除任务调度器异常:", e);
            emailUtil.sendEmail("删除任务:");
            throw e;
        }
        logger.info("删除一个任务=任务名:{}", identityKey);
    }
}
